package middleware

import (
	"bytes"
	"io"
	"time"

	"x-admin/backend/pkg/logger"

	"github.com/gin-gonic/gin"
	"github.com/sirupsen/logrus"
)

// LoggerMiddleware 日志中间件
func LoggerMiddleware() gin.HandlerFunc {
	return gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
		// 记录请求日志
		fields := logrus.Fields{
			"method":     param.Method,
			"path":       param.Path,
			"status":     param.StatusCode,
			"latency":    param.Latency,
			"client_ip":  param.ClientIP,
			"user_agent": param.Request.UserAgent(),
		}

		// 根据状态码选择日志级别
		if param.StatusCode >= 500 {
			logger.WithFields(fields).Error("HTTP Request")
		} else if param.StatusCode >= 400 {
			logger.WithFields(fields).Warn("HTTP Request")
		} else {
			logger.WithFields(fields).Info("HTTP Request")
		}

		return ""
	})
}

// ErrorLoggerMiddleware 错误日志中间件
func ErrorLoggerMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		// 捕获响应体
		blw := &bodyLogWriter{body: bytes.NewBufferString(""), ResponseWriter: c.Writer}
		c.Writer = blw

		// 处理请求
		c.Next()

		// 如果有错误，记录详细日志
		if len(c.Errors) > 0 {
			for _, err := range c.Errors {
				logger.WithFields(logrus.Fields{
					"method":      c.Request.Method,
					"path":        c.Request.URL.Path,
					"status":      c.Writer.Status(),
					"client_ip":   c.ClientIP,
					"user_agent":  c.Request.UserAgent(),
					"error":       err.Error(),
					"error_type":  err.Type,
					"response":    blw.body.String(),
				}).Error("Request Error")
			}
		}

		// 记录 4xx 和 5xx 响应的详细信息
		if c.Writer.Status() >= 400 {
			logger.WithFields(logrus.Fields{
				"method":     c.Request.Method,
				"path":       c.Request.URL.Path,
				"status":     c.Writer.Status(),
				"client_ip":  c.ClientIP,
				"user_agent": c.Request.UserAgent(),
				"response":   blw.body.String(),
			}).Error("HTTP Error Response")
		}
	}
}

// bodyLogWriter 用于捕获响应体的写入器
type bodyLogWriter struct {
	gin.ResponseWriter
	body *bytes.Buffer
}

func (w bodyLogWriter) Write(b []byte) (int, error) {
	w.body.Write(b)
	return w.ResponseWriter.Write(b)
}

// RequestLoggerMiddleware 请求详细日志中间件（开发环境使用）
func RequestLoggerMiddleware() gin.HandlerFunc {
	return func(c *gin.Context) {
		start := time.Now()

		// 读取请求体
		var requestBody []byte
		if c.Request.Body != nil {
			requestBody, _ = io.ReadAll(c.Request.Body)
			c.Request.Body = io.NopCloser(bytes.NewBuffer(requestBody))
		}

		// 记录请求开始
		logger.WithFields(logrus.Fields{
			"method":       c.Request.Method,
			"path":         c.Request.URL.Path,
			"query":        c.Request.URL.RawQuery,
			"client_ip":    c.ClientIP,
			"user_agent":   c.Request.UserAgent(),
			"content_type": c.Request.Header.Get("Content-Type"),
			"request_body": string(requestBody),
		}).Debug("Request Started")

		// 处理请求
		c.Next()

		// 记录请求结束
		latency := time.Since(start)
		logger.WithFields(logrus.Fields{
			"method":   c.Request.Method,
			"path":     c.Request.URL.Path,
			"status":   c.Writer.Status(),
			"latency":  latency,
			"client_ip": c.ClientIP(),
		}).Debug("Request Completed")
	}
}
